package org.xi2p;

public class Hold extends Note{
    double fullLength;
    double duration;
    double length = 0.0;

    @Override
    public void upgrade(double beat) {
        // 更新此note的中心点坐标
        if (beat > end){
            beat = end;
        }

        double _y;

        if (beat < at){
            length = fullLength;
            _y = (judgeline.noteYObject.getValue(at) -
                    judgeline.noteYObject.getValue(beat)) * (above ? 1 : -1) * speed;
        } else {
            length = fullLength * (end - beat) / duration;
            _y = 0;
        }

        double r = Math.pow(
                Math.pow(x, 2) + Math.pow(_y, 2), 0.5
        );

        double _angle;
        if (x > 0){
            _angle = judgeline.angle + Math.toDegrees(
                    Math.atan(_y / x)
            );
        } else if (x < 0) {
            _angle = judgeline.angle + Math.toDegrees(
                    Math.atan(_y / x)
            ) + 180;
        } else{
            _angle = judgeline.angle + (
                    _y >= 0 ? 90 : -90
            );
        }

        xInSurface = r * Math.cos(Math.toRadians(_angle)) + judgeline.x;
        yInSurface = -r * Math.sin(Math.toRadians(_angle)) + judgeline.y;

    }

    @Override
    public String blit(double beat) {
        // type x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8 r g b alpha
        double r;
        double g;
        double b;

        r = 10 + (highlight ? 32 : 0);
        g = 195 + (highlight ? 32 : 0);
        b = 255;

        double _length = length * (above ? 1 : -1);

        double x1, y1, x2, y2, x3, y3, x4, y4;
        {
            x1 = xInSurface + core.NOTE_R * Math.cos(Math.toRadians(judgeline.angle + core.NOTE_THETA));
            y1 = yInSurface - core.NOTE_R * Math.sin(Math.toRadians(judgeline.angle + core.NOTE_THETA));

            x2 = xInSurface + core.NOTE_R * Math.cos(Math.toRadians(judgeline.angle + 180 - core.NOTE_THETA));
            y2 = yInSurface - core.NOTE_R * Math.sin(Math.toRadians(judgeline.angle + 180 - core.NOTE_THETA));

            x3 = xInSurface + core.NOTE_R * Math.cos(Math.toRadians(judgeline.angle - 180 + core.NOTE_THETA));
            y3 = yInSurface - core.NOTE_R * Math.sin(Math.toRadians(judgeline.angle - 180 + core.NOTE_THETA));

            x4 = xInSurface + core.NOTE_R * Math.cos(Math.toRadians(judgeline.angle - core.NOTE_THETA));
            y4 = yInSurface - core.NOTE_R * Math.sin(Math.toRadians(judgeline.angle - core.NOTE_THETA));
        }

        double _angle = Math.toDegrees(Math.atan(_length / (core.BAR_WIDTH / 2) * 2));
        double _angle1 = Math.toRadians(judgeline.angle + _angle);
        double _angle2 = Math.toRadians(180 + judgeline.angle - _angle);
        double _r = Math.sqrt((_length * _length + ((core.BAR_WIDTH / 2) / 2) * ((core.BAR_WIDTH / 2) / 2)));
        double x5, x6, x7, x8, y5, y6, y7, y8;
        x5 = xInSurface + (core.BAR_WIDTH / 2) / 2 * Math.cos(Math.toRadians(judgeline.angle));
        y5 = yInSurface - (core.BAR_WIDTH / 2) / 2 * Math.sin(Math.toRadians(judgeline.angle));
        x6 = xInSurface - (core.BAR_WIDTH / 2) / 2 * Math.cos(Math.toRadians(judgeline.angle));
        y6 = yInSurface + (core.BAR_WIDTH / 2) / 2 * Math.sin(Math.toRadians(judgeline.angle));
        x7 = xInSurface + _r * Math.cos(_angle2);
        y7 = yInSurface - _r * Math.sin(_angle2);
        x8 = xInSurface + _r * Math.cos(_angle1);
        y8 = yInSurface - _r * Math.sin(_angle1);

//        double alpha = judgeline.alpha;
//        double alpha = 255.0;
        double alpha = (miss) ? 122 : 255;
        return "%d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f|".formatted(
                type, x1, y1, x2, y2, x3, y3, x4, y4, x5, x6, x7, x8, y5, y6, y7, y8, r, g, b, alpha
        );

    }

    public Hold(Judgeline judgeline, int type, double x, double at, double end, Boolean above, double alpha, Boolean fake, double speed) {
        super(judgeline, type, x, at, end, above, alpha, fake, speed);
        fullLength = (judgeline.noteYObject.getValue(end) - judgeline.noteYObject.getValue(at)) * speed;
        duration = end - at;

    }


}
